#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
测试 https://proxy.scdn.io/text.php 提供的代理是否可用
"""

import requests
import concurrent.futures
from urllib.parse import urlparse
import time

# 目标测试网站
TEST_URL = "https://data.eastmoney.com"
TIMEOUT = 5
MAX_WORKERS = 20  # 并发测试数量


def parse_proxies_from_url(url):
    """从指定URL获取代理列表"""
    try:
        print(f"正在从 {url} 获取代理列表...")
        response = requests.get(url, timeout=10)
        response.raise_for_status()
        
        # 解析代理列表，每行一个 IP:PORT
        proxies = []
        for line in response.text.strip().split('\n'):
            line = line.strip()
            if not line:
                continue
            
            # 简单的IP:PORT格式验证
            if ':' in line:
                parts = line.split(':')
                if len(parts) == 2:
                    ip = parts[0].strip()
                    port = parts[1].strip()
                    # 跳过明显无效的（如包含特殊字符）
                    if port.isdigit() and '.' in ip:
                        # 格式化为 ip:port
                        proxy = f"{ip}:{port}"
                        proxies.append(proxy)
        
        print(f"从网页获取到 {len(proxies)} 个代理")
        return proxies
    except Exception as e:
        print(f"获取代理列表失败: {e}")
        return []


def test_proxy(proxy):
    """测试单个代理是否可用"""
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0',
        'Accept': '*/*',
        'Connection': 'keep-alive',
        'Accept-Language': 'zh-CN,zh;q=0.8'
    }
    
    # 格式化代理URL
    if not proxy.startswith('http://') and not proxy.startswith('https://'):
        proxy_url = f"http://{proxy}"
    else:
        proxy_url = proxy
    
    proxies = {
        "http": proxy_url,
        "https": proxy_url
    }
    
    try:
        # 使用 HEAD 方法测试，更快
        r = requests.head(
            TEST_URL,
            headers=headers,
            proxies=proxies,
            timeout=TIMEOUT,
            verify=False
        )
        if r.status_code == 200:
            return True, None
        else:
            return False, f"状态码: {r.status_code}"
    except requests.exceptions.Timeout:
        return False, "连接超时"
    except requests.exceptions.ProxyError as e:
        return False, f"代理错误: {str(e)[:50]}"
    except requests.exceptions.ConnectionError as e:
        return False, f"连接错误: {str(e)[:50]}"
    except Exception as e:
        return False, f"其他错误: {str(e)[:50]}"


def test_proxies_batch(proxies, max_workers=MAX_WORKERS):
    """批量测试代理"""
    valid_proxies = []
    invalid_proxies = []
    total = len(proxies)
    
    print(f"\n开始测试 {total} 个代理，使用 {max_workers} 个并发线程...")
    print(f"目标网站: {TEST_URL}")
    print(f"超时设置: {TIMEOUT} 秒\n")
    
    start_time = time.time()
    
    with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
        # 提交所有任务
        future_to_proxy = {executor.submit(test_proxy, proxy): proxy for proxy in proxies}
        
        # 收集结果
        completed = 0
        for future in concurrent.futures.as_completed(future_to_proxy):
            proxy = future_to_proxy[future]
            completed += 1
            
            try:
                is_valid, error_msg = future.result()
                if is_valid:
                    valid_proxies.append(proxy)
                    print(f"[{completed}/{total}] ✓ {proxy} - 可用")
                else:
                    invalid_proxies.append((proxy, error_msg))
                    if completed % 10 == 0 or completed == total:
                        print(f"[{completed}/{total}] ✗ {proxy} - 不可用 ({error_msg})")
            except Exception as e:
                invalid_proxies.append((proxy, f"测试异常: {str(e)}"))
                if completed % 10 == 0 or completed == total:
                    print(f"[{completed}/{total}] ✗ {proxy} - 测试异常")
            
            # 每完成100个显示进度
            if completed % 100 == 0:
                elapsed = time.time() - start_time
                print(f"\n进度: {completed}/{total} ({completed*100//total}%) | "
                      f"已用时间: {elapsed:.1f}秒 | "
                      f"可用代理: {len(valid_proxies)} 个\n")
    
    elapsed = time.time() - start_time
    
    print(f"\n{'='*60}")
    print(f"测试完成！")
    print(f"总代理数: {total}")
    print(f"可用代理: {len(valid_proxies)} ({len(valid_proxies)*100//total if total > 0 else 0}%)")
    print(f"不可用代理: {len(invalid_proxies)}")
    print(f"总耗时: {elapsed:.1f} 秒")
    print(f"{'='*60}\n")
    
    return valid_proxies, invalid_proxies


def save_valid_proxies(valid_proxies, filename='dev/可用代理列表.txt'):
    """保存可用的代理列表"""
    if not valid_proxies:
        print("没有可用的代理，不保存文件")
        return
    
    try:
        with open(filename, 'w', encoding='utf-8') as f:
            for proxy in valid_proxies:
                f.write(f"{proxy}\n")
        print(f"已保存 {len(valid_proxies)} 个可用代理到: {filename}")
    except Exception as e:
        print(f"保存代理列表失败: {e}")


def main():
    # 获取代理列表
    proxy_url = "https://proxy.scdn.io/text.php"
    proxies = parse_proxies_from_url(proxy_url)
    
    if not proxies:
        print("未能获取到代理列表，退出")
        return
    
    # 为了测试速度，可以限制测试数量（取消注释下面这行）
    # proxies = proxies[:100]  # 只测试前100个
    
    # 批量测试
    valid_proxies, invalid_proxies = test_proxies_batch(proxies)
    
    # 显示结果
    if valid_proxies:
        print(f"\n可用的代理列表（前10个）:")
        for i, proxy in enumerate(valid_proxies[:10], 1):
            print(f"  {i}. {proxy}")
        if len(valid_proxies) > 10:
            print(f"  ... 还有 {len(valid_proxies) - 10} 个可用代理")
        
        # 保存结果
        save_valid_proxies(valid_proxies)
        
        # 生成用于写入 proxy.txt 的命令
        print(f"\n{'='*60}")
        print("可以使用以下命令将可用代理写入代理文件:")
        print(f"{'='*60}")
        print(f"# 清除旧代理并写入新代理（只保留前50个最快的）")
        print(f"sudo sh -c 'echo \"{valid_proxies[0]}\" > /data/instockproxy.txt'")
        for proxy in valid_proxies[1:50]:  # 最多保存50个
            print(f"sudo sh -c 'echo \"{proxy}\" >> /data/instockproxy.txt'")
    else:
        print("\n很遗憾，没有找到可用的代理")


if __name__ == "__main__":
    # 禁用SSL警告
    import urllib3
    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
    
    main()

